<?php
namespace Wx\Model;
use Think\Model;
/**
 * 微信支付模块
 */
class WxpayModel extends Model {


    private $POSTDATA;
    public $notify;
    public function __construct(){
        
        vendor('WxPayPubHelper.WxPayPubHelper');
        parent::__construct();
        $this->logPath = "data/".strftime("%Y-%m-%d",time())."-wxpay.log";
        $this->logPathStatus = 1;
        $config = M('Payments')->field('payName,payConfig')->where(array('payCode' => 'weixin', 'enabled' => 1))->find();
        $payConfig = json_decode($config['payConfig']);
        $this->notify = new \Notify_pub($payConfig->appId, $payConfig->mchId, $payConfig->apiKey, $payConfig->appsecret);


    }
    

    
    
    public function check(){

        
        $xml = $GLOBALS['HTTP_RAW_POST_DATA'];


        if($xml===null){
            $this->log_result($this->logPath,'[非微信异步通知请求]');
        }else{
            $this->notify->saveData($xml);
            $this->POSTDATA = $this->notify->data;
        }
        if($this->notify->checkSign() === TRUE){
            $this->checkResultCode($this->notify);
            $this->log_result($this->logPath,'[签名通过]');

        }elseif ($this->notify->checkSign() === FALSE){
            
            $this->log_result($this->logPath,'[签名失败]');
            return;
        }else{
            return;

        }


    }

    private function checkResultCode($notify){

        if ($notify->data["return_code"] == "SUCCESS") {
            $this->actionData();
            $this->log_result($this->logPath,"【通信标识return_code】:".$notify->data["return_code"]);
            $this->log_result($this->logPath,"【通信标识return_msg】:".$notify->data["return_msg"]);

        }
        else {

            $this->log_result($this->logPath,"【通信标识return_code】:".$notify->data["return_code"]);
            $this->log_result($this->logPath,"【通信标识return_msg】:".$notify->data["return_msg"]);

        }
    }

    private function actionData(){
        $out_trade_no_text=$this->POSTDATA['out_trade_no'];
        $this->log_result($this->logPath,"【out_trade_no】:".$out_trade_no_text);
        $temp=explode('_', $out_trade_no_text);
        $out_trade_no=$temp[1];
        $this->log_result($this->logPath,"【out_trade_no】:".$out_trade_no);
        //判断是订单付款还是充值
        $type=M('orders_payid')->where(array('id'=>$out_trade_no))->getField('type');//1订单，2充值
        $this->log_result($this->logPath,"【判断是1订单付款2充值】:".$type);
        switch ($type){
            case 1:
                $this->log_result($this->logPath,"【进入订单付款");
                $this->addOrder($out_trade_no);
                break;
            case 2:
                $this->log_result($this->logPath,"【进入充值流程");
                $this->addMoney($out_trade_no);
                break;
            default:
                break;
        }


    }


    private function addOrder($out_trade_no){
        M()->startTrans ();
        $order_id=M('orders_payid')->where(array('pid'=>$out_trade_no))->field('orderId')->select();
        $orderids='';
        foreach ($order_id as $K=>$v){
            $orderids.=$v['orderId'].',';
        }
        $orderids=rtrim($orderids,',');
        $ispayInfo=M('orders')->where(array('orderId'=>array('in',$orderids)))->field('userId,isPay,orderNo,orderId,shopId,needPay')->select();
        $ispay=false;
        foreach($ispayInfo as $k=>$v){
            if($v['isPay']==1){
                $ispay=true;
            }
        }
        $this->log_result($this->logPath,"【检查订单是否已经付款1是付款,0是未付款】".$ispay);
        //已经付过
        if($ispay){
            $this->log_result($this->logPath,"【订单已支付结束】");
            echo 'success';return;
        }

        $orderNos='';
        foreach($ispayInfo as $k=>$v){
            $orderNos.=$v['orderNo'].',';
            if($v['isPay']==1){
                $ispay=false;
            }
        }
        $orderNos=trim($orderNos,',');

        $saveData['isPay']=1;
        $saveData['orderStatus']=0;
        $saveData['paytime']=time();
        $saveData['payType']=2; //微信支付
        $map['orderId']=array('in',$orderids);
        $res=M('orders')->where($map)->data($saveData)->save();
        $this->log_result($this->logPath,"【更新订单数据为微信支付1修改成功0修改失败:】".$res);
        
        $userId=$ispayInfo[0]['userId'];
        if(!$userId){
            $this->log_result($this->logPath,"【用户不存在结束】");
            echo 'success';return;
        }
        $payMoney = $this->POSTDATA['total_fee']/100;
        $this->log_result($this->logPath,"【获取通知中的金额:】".$payMoney);
        $tradeNo = $this->POSTDATA['transaction_id'];//流水号
        $this->log_result($this->logPath,"【获取通知中的流水号:】".$tradeNo);
        $notify_time = date('Y-m-d H:i:s',strtotime($this->POSTDATA['time_end']));
        $this->log_result($this->logPath,"【获取通知中的付款时间:】".$notify_time);
        $buyer_email = $this->POSTDATA['openid']; // 买家帐号
        $this->log_result($this->logPath,"【获取通知中的付款微信id:】".$buyer_email);

        $userMoney=M('users')->where(array('userId'=>$userId))->getField('userMoney');

        
//        $D=$this->scoreRecord(1,$payMoney,$orderNos,1,$userId);
        //$this->log_result($this->logPath,"【操作积分】:\n".$D."\n");
//        $this->log_result($this->logPath,"【操作积分:】".$D);

        $E=$this->payRecord(0,$orderNos,time(),$tradeNo,$payMoney,$userId,0,'',$notify_time,$buyer_email);
        $this->log_result($this->logPath,"【操作支付:】".$E);


        $F=$this->moneyRecord(1,$payMoney,$orderNos,0,$userId,$userMoney,'',2);
        $this->log_result($this->logPath,"【操作支付记录:】".$F);

        //$this->log_result($this->logPath,"【操作付款记录】:\n".$E."\n");
        //操作库存
        $ogField="goodsId,goodsNums,goodsAttrId";
        $order_goods=M('order_goods')->where(array('orderId'=>array('in',"$orderids")))->select();

        $goodsDB=M('goods');
        $attrDB=M('goods_attributes');
        $stock=true;
        foreach ($order_goods as $k=>$v){
            $goodsRes= $goodsDB->where(array('goodsId'=>$v['goodsId']))->setDec('goodsStock',$v['goodsNums']);
            $goodsSaleCount= $goodsDB->where(array('goodsId'=>$v['goodsId']))->setInc('saleCount',$v['goodsNums']);//增加销量
            if($v['goodsAttrId']){
                $attrRes= $attrDB->where(array('id'=>array('in',$v['goodsAttrId'])))->setDec('attrStock',$v['goodsNums']);
                if(!$goodsRes||!$attrRes){
                    $stock=false;
                }
            }
            if(!$goodsRes){
                $stock=false;
            }
        }
        $this->log_result($this->logPath,"【操作库存:】".$stock);

        // $this->log_result($this->logPath,"【操作库存】:\n".$stock."\n");
        if(!$stock){
            M()->rollback();
            $this->log_result($this->logPath,"【操作库存失败:事务回滚】");
            echo 'FAIL';
            return;
        }
        $ordersPayidStatus = array('actionStatus'=>1);
        $payIdStatus=M('orders_payid')->where(array('id'=>$out_trade_no))->setField($ordersPayidStatus);
        //操作库存结束
        if($res&&$E&&$F&&$payIdStatus){
            //订单日志记录
            $morm = M('order_reminds');
            $mlogo = M('log_orders');
            foreach ($ispayInfo as $k=>$v){
                $data = array();
                $data["orderId"] = $v['orderId'];
                $data["logContent"] = '付款成功';
                $data["logUserId"] = $userId;
                $data["logType"] = 0;
                $data["logTime"] = date('Y-m-d H:i:s');
                $mlogo->add($data);
                $this->log_result($this->logPath,"【订单日志记录】");

                //建立订单提醒
                $data = array();
                $data["orderId"] = $v['orderId'];
                $data["shopId"] = $v['shopId'];
                $data["userId"] =  $userId;
                $data["userType"] = 0;
                $data["remindType"] = 0;
                $data["createTime"] = date("Y-m-d H:i:s");
                $morm->add($data);
                $this->log_result($this->logPath,"【建立订单提醒】");

            }
            M()->commit();
            $this->log_result($this->logPath,"【事务提交】");
            echo 'success';return;
        }else{
            $this->log_result($this->logPath,"【事务回滚】");
            M()->rollback();
            echo 'FAIL';
            return;
        }
        
        
    }
    
    
    
    private function addMoney($out_trade_no){
        M()->startTrans ();
        $isTopUp=M('top_up')->where(array('topupNo'=>$out_trade_no))->find();
        $status=$isTopUp['status'];
        $payMoney = $this->POSTDATA['total_fee']/100;
        $tradeNo = $this->POSTDATA['transaction_id'];//流水号
        $notify_time = date('Y-m-d H:i:s',strtotime($this->POSTDATA['time_end']));
        $buyer_email = $this->POSTDATA['openid']; // 买家帐号

        $this->log_result($this->logPath,"【充值订单号】".$out_trade_no);
        if($status==1){
            $this->notify->setReturnParameter("return_code","SUCCESS");//设置返回码
            echo "success";exit;
        }

        $userId=$isTopUp['userid'];
        $this->log_result($this->logPath,"【out_trade_no】".$out_trade_no);

        //充值表
        $a = array('status'=>1);


        $A=M('top_up')->where(array('topupNo'=>$out_trade_no))->setField($a);



        $this->log_result($this->logPath,"【充值状态】".$A);
        $this->log_result($this->logPath,"【充值状态金额】".$payMoney);

        $YE=M('users')->where(array('userId'=>$userId))->getField('userMoney');//余额

        //增加余额
        $this->log_result($this->logPath,"【充值账号余额】".$YE);

        $B=M('users')->where(array('userId'=>$userId))->setInc('userMoney',$payMoney);
        $this->log_result($this->logPath,"【更新充值账号余额状态】".$B);


        //余额变动记录
        $C=$this->moneyRecord(3,$payMoney,$out_trade_no,1,$userId,$YE,'充值',2);
        $this->log_result($this->logPath,"【余额变动记录】".$C);


        //付款记录
        $E=$this->payRecord(2,$out_trade_no,time(),$tradeNo,$payMoney,$userId,0,'',$notify_time,$buyer_email);
        $this->log_result($this->logPath,"【付款记录】".$E);

        $this->log_result($this->logPath,"【提交】".$A.$B.$C.$E);

        $ordersPayidStatus = array('actionStatus'=>1);
        $payIdStatus=M('orders_payid')->where(array('id'=>$out_trade_no))->setField($ordersPayidStatus);

        if($A&&$B&&$C&&$E&&$payIdStatus){
            $this->log_result($this->logPath,"【提交事务】");
            M()->commit();
            $this->notify->setReturnParameter("return_code","SUCCESS");//设置返回码
            echo 'success';exit;
        }else{
            $this->log_result($this->logPath,"【回滚事务】");
            M()->rollback();
            echo 'FAIL';
        }
        
        
        
        
    }


    // 金额操作记录
    /**
     * 构造函数
     * @param $type 操作类型,1下单，2取消订单，3充值，4提现,5订单无效
     * @param $money 金额
     * @param $orderNo 订单编号或者充值ID
     * @param $IncDec 余额变动 0为减，1加
     * @param $userid 用户ID
     * @param $balance 余额
     * @param $remark 其它备注信息
     */
    private function moneyRecord($type = '', $money = 0, $orderNo = '', $IncDec = '', $userid = 0, $balance = 0,$remark='',$payWay=0) {
        $db = M ( 'money_record' );
        $data ['type'] = $type;
        $data ['money'] = $money;
        $data ['time'] = time ();
        $data ['ip'] = get_client_ip ();
        $data ['orderNo'] = $orderNo;
        $data ['IncDec'] = $IncDec;
        $data ['userid'] = $userid;
        $data ['balance'] = $balance;
        $data ['remark'] = $remark;
        $data ['payWay'] = $payWay;
        $res = $db->add ( $data );
        return $res;
    }

// 积分操作记录
    /**
     * 构造函数
     * @param $type 1购物，2取消订单，3充值，4订单无效，5活动,6评价订单
     * @param $score 积分
     * @param $shopid 店铺ID
     * @param $orderid 订单ID或者充值ID
     * @param $IncDec 积分变动0为减，1加
     * @param $userid 用户ID
     * @param $totalscore 用户剩余总积分
     */
    private function scoreRecord($type = '', $payMoney=0, $orderNo = '', $IncDec = '', $userid = 0) {
        $log_name= "Public/wx_call_back.log";//log文件路径

        $score=floor($payMoney);
//        if($score<=0){
//            return 1;
//        }
        $totalscore=M('users')->where(array('userId'=>$userid))->getField('userScore');
        $db = M ( 'score_record' );
        $data ['score'] = $score;
        $data ['type'] = $type;
        $data ['time'] = time ();
        $data ['ip'] = get_client_ip ();
        $data ['orderNo'] = $orderNo;
        $data ['IncDec'] = $IncDec;
        $data ['userid'] = $userid;
        $data ['totalscore'] = $totalscore;
        $res = $db->add ( $data );

        $this->log_result($log_name,"【积分操作记录】".$res);

        return $res;
    }
    // 支付记录
    /**
     * 构造函数
     * @param $payType 支付类型 0余额支付，1支付宝，2微信
     * @param $orderNo 订单编号
     * @param $payTime 付款时间
     * @param $out_trade_no 第三方返回的流水号
     * @param $payMoney 金额
     * @param $userId 用户ID
     * @param $type 0订单，1充值
     * @param $notify_id 通知ID
     * @param $notify_time 通知时间
     * @param $buyer_email 支付宝帐号或者微信OPENID
     * */
    private function payRecord($payType=0,$orderNo,$payTime,$out_trade_no,$payMoney,$userId,$type=0,$notify_id,$notify_time,$buyer_email){
        $data['payType']=$payType;//支付类型 0余额支付，1支付宝，2微信
        $data['orderNo']=$orderNo;
        $data['payTime']=$payTime;
        $data['out_trade_no']=$out_trade_no;
        $data['payMoney']=$payMoney;
        $data['userId']=$userId;
        $data['type']=$type;
        $data['notify_id']=$notify_id;
        $data['notify_time']=$notify_time;
        $data['buyer_email']=$buyer_email;
        $db=M('pay_record');
        $res=$db->add($data);
        return $res;
    }


    private function log_result($file,$word){
      if($this->logPathStatus==1){
            $fp = fopen($file,"a");
            flock($fp, LOCK_EX) ;
            fwrite($fp,"日期：".strftime("%Y-%m-%d-%H:%M:%S",time()).'->'.$word."\n");
            flock($fp, LOCK_UN);
            fclose($fp);
            }

    }


    public function qcodeImg($url){



        $path = 'Upload/qrcode/'.md5($url).'.png';
        if(!file_exists($path)){
            mkdir('Upload/qrcode/');
            require $_SERVER['DOCUMENT_ROOT'].'/Library/Org/Util/'.'phpqrcode.php';
            $errorCorrectionLevel = 'L';//容错级别
            $matrixPointSize = 6;//生成图片大小
//生成二维码图片
            $ss = new \QRcode();
            $ss::png($url, $path, $errorCorrectionLevel, $matrixPointSize, 2);


        }


        return $path;
    }

    public function wxNativeCheck(){

        $id = I('payid');
        $reslut = array('status'=>0,'message'=>'未支付');
        $res = M('orders_payid')->field('id')->where(array('id'=>$id,'actionStatus'=>1))->find();

        if($res){
            $reslut = array('status'=>1,'message'=>'订单处理成功');
        }


        return $reslut;
    }
    
    

	
}